/*
 * $Id: Plugin.java 84 2009-04-23 11:04:29Z meyer@alphatec.de $
 * 
 *
 * Copyright 2009 DeltaDesk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package deltadesk.gui.deltagui;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import org.java.plugin.PluginManager;
import org.java.plugin.registry.Extension;
import org.java.plugin.registry.ExtensionPoint;

import deltadesk.gui.deltagui.display.FullscreenWindow;
import deltadesk.gui.deltagui.validation.ValidationManager;
import deltadesk.gui.deltagui.widget.Composite;
import deltadesk.gui.deltagui.widget.Desktop;

/**
 * Deltadesk DeltaGUI plugin.
 * 
 * @author Andreas Meyer
 * @version $Revision: 84 $
 */
public final class Plugin extends org.java.plugin.Plugin {

	/** This plug-in ID. */
	public static final String PLUGIN_ID = "deltadesk.gui.deltagui";

	/** The extension point for the main composite. */
	public static final String EP_MAIN_COMPOSITE = "mainComposite";

	/** Our main window. */
	private FullscreenWindow window;

	/** The desktop. */
	private Desktop desktop;

	/**
	 * @see org.java.plugin.Plugin#doStart()
	 */
	protected void doStart() throws Exception {
		log.info("+DeltaDesk.DeltaGUI");

		// create main window
		window = new FullscreenWindow();
		registerKeyListener();

		desktop = new Desktop();
		desktop.setShowFPS(true);

		final String name = getDescriptor().getAttribute("app.name").getValue();
		window.show(0, name, desktop);
		desktop.setSize(window.getWidth(), window.getHeight());
		
		getManager().registerListener(new PluginManager.EventListenerAdapter() {

			public void pluginActivated(final org.java.plugin.Plugin p) {
				if(getDescriptor().equals(p.getDescriptor())) {
					try {
						loadMainComposite();
					} catch (final Exception e) {
						
						log.error("Failed loaing main composite.", e);
						getManager().shutdown();
					}
				} // end if
			}
		});

		log.info("*DeltaDesk.DeltaGUI");
	}

	/**
	 * Set a new display mode.
	 * 
	 * @param dm
	 * @return
	 */
	// TODO: refactor to FullscreenWindow
	/*
	 * public boolean setDisplayMode(final DisplayMode dm) {
	 * 
	 * try {
	 * 
	 * device.setDisplayMode(dm); rootPane.showCursor(false);
	 * getDesktop().setSize(dm.getWidth(), dm.getHeight());
	 * getDesktop().invalidate(); getDesktop().setUnrendered(); } catch
	 * (Exception e) { return false; }
	 * 
	 * return true; }
	 */

	/**
	 * Switch back to the original display mode and exit.
	 * 
	 * @see org.java.plugin.Plugin#doStop()
	 */
	protected void doStop() throws Exception {
		log.info("-DeltaDesk.DeltaGUI");

		ValidationManager.getInstance().stop();
		desktop.removeAll();
		window.hide();

		log.info("_DeltaDesk.DeltaGUI");
	}

	/**
	 * Resolve main composite from extension point.
	 * 
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * 
	 */
	private void loadMainComposite() throws ClassNotFoundException,
			                                InstantiationException,
			                                IllegalAccessException {
		
		final String targetExt = getDescriptor().getAttribute("mainComposite").getValue();

		final ExtensionPoint ep = getDescriptor().
			getExtensionPoint(EP_MAIN_COMPOSITE);

		for (final Extension ex : ep.getConnectedExtensions()) {

			if (targetExt.equals(ex.getId())) {

				log.info(" Loading " + ex.getId());
				final String classStr = ex.getParameter("class").valueAsString();
				final Class<?> c = getManager().getPluginClassLoader(
						ex.getDeclaringPluginDescriptor()).loadClass(classStr);
				final Object o = c.newInstance();
				desktop.setMainComposite((Composite) o);
			} // end if
		} // end for
	}

	/**
	 * Handle key events.
	 * 
	 */
	private void registerKeyListener() {

		window.addKeyListener(new KeyAdapter() {

			public void keyReleased(final KeyEvent e) {

				// Handle Ctrl-C or ESC for exiting the application
				if (e.getKeyCode() == KeyEvent.VK_C && e.isControlDown()
						|| e.getKeyCode() == KeyEvent.VK_ESCAPE) {

					log.info("Shutdown initiated");
					getManager().shutdown();
				} else {
					desktop.postKeyEvent(e);
				}
			}
		});
	}

}
